package com.auxgroup.hr.front.dozer;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

import org.dozer.DozerBeanMapper;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.auxgroup.hr.front.dozer.exception.MappingException;

/**
 * 
 * @author liuzhe
 *
 */
@Component("dozerMapper")
public class ObjectMapperDozerImpl implements IObjectMapper {

	@Autowired
	private Mapper mapper;


	public ObjectMapperDozerImpl() {
		super();
	}

	public ObjectMapperDozerImpl(DozerBeanMapper mapper) {
		super();
		this.mapper = mapper;
	}

	@Override
	public <T> T map(Object source, Class<T> destinationClass)
			throws MappingException {
		try {
			if (source != null) {
				return mapper.map(source, destinationClass);
			}
			return null;
		} catch (org.dozer.MappingException e) {
			throw new MappingException(e);
		}
	}

	@Override
	public void map(Object source, Object destination) throws MappingException {
		try {
			if (source != null) {
				mapper.map(source, destination);
			}
		} catch (org.dozer.MappingException e) {
			throw new MappingException(e);

		}
	}

	@Override
	public <T> T map(Object source, Class<T> destinationClass, String mapId)
			throws MappingException {
		try {
			if (source != null) {
				return mapper.map(source, destinationClass, mapId);
			}
			return null;
		} catch (org.dozer.MappingException e) {
			throw new MappingException(e);

		}
	}

	@Override
	public void map(Object source, Object destination, String mapId)
			throws MappingException {
		try {
			mapper.map(source, destination, mapId);
		} catch (org.dozer.MappingException e) {
			throw new MappingException(e);

		}
	}

	@Override
	public <T> void map(Collection<?> source, Collection<T> dest,
			Class<T> destinationClass) throws MappingException {
		try {
			if (source != null && source.size() > 0 && dest != null) {
				for (Object object : source) {
					T map = mapper.map(object, destinationClass);
					dest.add(map);
				}
			}
		} catch (org.dozer.MappingException e) {
			throw new MappingException(e);
		}

	}

	@Override
	public <T> void map(Collection<?> source, Collection<T> dest,
			Class<T> destinationClass, String mapId) throws MappingException {
		try {
			if (source != null && source.size() > 0 && dest != null) {
				for (Object object : source) {
					dest.add(mapper.map(object, destinationClass, mapId));
				}
			}
		} catch (org.dozer.MappingException e) {
			throw new MappingException(e);
		}

	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public <T> Collection<T> map(Collection<?> source,
			Class<T> destinationClass,
			Class<? extends Collection> destinationCollectionClass)
			throws MappingException {
		try {
			if (source != null) {
				Collection result = getCollectionIns(destinationCollectionClass);
				if (source.size() > 0) {
					for (Object obj : source) {
						T dest = mapper.map(obj, destinationClass);
						result.add(dest);
					}
				}
				return result;
			} else {
				return null;
			}
		} catch (org.dozer.MappingException e) {
			throw new MappingException(e);
		} catch (Exception e) {
			throw new MappingException(e);
		}
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public <T> Collection<T> map(Collection<?> source,
			Class<T> destinationClass,
			Class<? extends Collection> destinationCollectionClass, String mapId)
			throws MappingException {
		try {
			if (source != null && destinationCollectionClass != null) {
				Collection result = getCollectionIns(destinationCollectionClass);
				if (source.size() > 0) {
					for (Object obj : source) {
						result.add(mapper.map(obj, destinationClass, mapId));
					}
				}
				return result;
			} else {
				return null;
			}
		} catch (org.dozer.MappingException e) {
			throw new MappingException(e);
		} catch (Exception e) {
			throw new MappingException(e);
		}
	}

	/**
	 * 获取指定Collection类型的实例
	 * @param destinationCollectionClass
	 * @return 指定Collection类型的实例
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	@SuppressWarnings("rawtypes")
	private Collection getCollectionIns(
			Class<? extends Collection> destinationCollectionClass)
			throws InstantiationException, IllegalAccessException {
		Collection result = null;
		if (destinationCollectionClass.isInterface()) {
			if (List.class.equals(destinationCollectionClass)) {
				result = new ArrayList();
			} else {
				if (Set.class.equals(destinationCollectionClass)) {
					result = new HashSet();
				} else {
					if (Queue.class.equals(destinationCollectionClass)) {
						result = new LinkedList();
					}
				}
			}
		} else {
			result = destinationCollectionClass.newInstance();
		}
		return result;
	}

}
